//
//  SFCCredentials.m
//  SVNForCocoa
//
//  Created by Jeremy Pereira on 25/11/2013.
//  Copyright (c) 2013 Jeremy Pereira. All rights reserved.
//

#import "SFCCredentials.h"
#import "SFCLib+Internals.h"

@interface SFCCredentials ()

-(id) initWithSvnCredentials: (const void*) svnCredentials;

@end

@implementation SFCCredentials

@synthesize maySave = _maySave;

-(id) init
{
    return [self initWithMaySave: false];
}

-(id) initWithMaySave:(bool)maySave
{
    self = [super init];
    if (self != nil)
    {
        _maySave = maySave;
    }
    return self;
}

-(id) initWithSvnCredentials: (const void*) svnCredentials
{
    @throw [NSException exceptionWithName: [self className]
                                   reason: [NSString stringWithFormat: @"%s not implemented", __PRETTY_FUNCTION__]
                                 userInfo: nil];
}

-(void*) svnCredentialsWithAprPool: (apr_pool_t *)aprPool
{
    @throw [NSException exceptionWithName: [self className]
                                   reason: [NSString stringWithFormat: @"%s not implemented", __PRETTY_FUNCTION__]
                                 userInfo: nil];
}


+(SFCCredentials*) credentialsForKind: (NSString*) kind
                       svnCredentials: (const void*) svnCredentials
{
    id theClass = nil;

    if ([@""SVN_AUTH_CRED_USERNAME isEqualToString: kind])
    {
		theClass = [SFCUserNameCredentials class];
    }
    else if ([@""SVN_AUTH_CRED_SIMPLE isEqualToString: kind])
    {
		theClass = [SFCSimpleCredentials class];
    }

    if (theClass == nil)
    {
        @throw [NSException exceptionWithName: [self className]
                                       reason: [NSString stringWithFormat:
                                                @"%s doesn't understand kind %@",
                                                __PRETTY_FUNCTION__,
                                                kind]
                                     userInfo: nil];
    }
    return [[theClass alloc] initWithSvnCredentials: svnCredentials];
}

@end

@implementation SFCUserNameCredentials
{
    NSString* _name;
    bool _maySave;
}

-(id) init
{
    return [self initWithName: nil maySave: false];
}

-(id) initWithMaySave:(bool)maySave
{
    return [self initWithName: nil maySave: maySave];
}

-(id) initWithName: (NSString*) name maySave: (bool) maySave
{
    self = [super initWithMaySave: maySave];
    if (self != nil)
    {
		_name = name;
        _maySave = maySave;
    }
    return self;
}


-(id) initWithSvnCredentials: (const void*) svnCredentials
{
    const svn_auth_cred_username_t* userNameCreds = svnCredentials;
	NSString* name = [NSString stringWithUTF8String: userNameCreds->username];
    bool maySave = userNameCreds->may_save;
    return [self initWithName: name maySave: maySave];
}


-(void*) svnCredentialsWithAprPool: (apr_pool_t *)aprPool
{
    svn_auth_cred_username_t* ret = apr_palloc(aprPool, sizeof(svn_auth_cred_username_t));
    ret->username = [_name svnStringWithAprPool: aprPool]->data;
    ret->may_save = [self maySave];
    return ret;
}

@end

@implementation SFCSimpleCredentials
{
    NSString* _name;
    NSString* _password;
}

-(id) initWithName:(NSString *)name
          password:(NSString *)password
           maySave:(bool)maySave
{
    self = [super initWithMaySave: maySave];
    if (self != nil)
    {
		_name = name;
        _password = password;
    }
    return self;
}


-(id) initWithSvnCredentials: (const void*) svnCredentials
{
    const svn_auth_cred_simple_t* simpleCreds = svnCredentials;
	NSString* name = [NSString stringWithUTF8String: simpleCreds->username];
	NSString* password = [NSString stringWithUTF8String: simpleCreds->password];
    bool maySave = simpleCreds->may_save;
    return [self initWithName: name password: password maySave: maySave];
}



-(void*) svnCredentialsWithAprPool: (apr_pool_t *)aprPool
{
    svn_auth_cred_simple_t* ret = apr_palloc(aprPool, sizeof(svn_auth_cred_simple_t));
    ret->username = [_name svnStringWithAprPool: aprPool]->data;
    ret->password = [_password svnStringWithAprPool: aprPool]->data;
    ret->may_save = [self maySave];
    return ret;
}

@end
